package com.bidevalution.controller.task;

import com.bidevalution.business.context.StepStage;
import com.bidevalution.business.service.BeSectionMethodService;
import com.bidevalution.business.service.BeSectionStepJobService;
import com.bidevalution.dao.entity.BeSectionMethod;
import com.bidevalution.dao.entity.BeSectionStepJob;
import com.bidevalution.support.context.Constants;
import com.bidevalution.support.util.RedisLockTool;
import com.qtp.core.redis.RedisUtil;
import com.qtp.core.util.DateUtil;
import lombok.extern.log4j.Log4j2;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @description: 提前执行环节任务定时器
 * 主要用于查询环节任务需要提前执行且处于可以执行状态，后台执行这部分任务
 * @author: xiayf
 * @date: 2019-11-01 17:12
 */

@Component
public class AdvanceExecuteJobTask {

    @Autowired
    private BeSectionStepJobService beSectionStepJobService;
    @Autowired
    private BeSectionMethodService beSectionMethodService;
    /**
     * 提前执行环节任务锁标识
     */
    private static String ADVANCE_EXECUTE_JOB_LOCK = "ADVANCE_EXECUTE_JOB_LOCK";

    private Logger log = LogManager.getLogger(getClass());

    @Scheduled(cron = "0/30 * * * * ? ")
    public void execute() {
        //查询当天开标项目需要提前执行的任务且处于可以执行状态(只需要环节id即可)
        List<BeSectionStepJob> beSectionStepJobList = beSectionStepJobService.queryAdvanceExecuteJobToday();
        if (beSectionStepJobList != null && !beSectionStepJobList.isEmpty()) {
            for (BeSectionStepJob beSectionStepJob : beSectionStepJobList) {
                try {
                    //加锁
                    boolean lock = RedisLockTool.getDistributedLock(RedisUtil.getJedis(), ADVANCE_EXECUTE_JOB_LOCK + beSectionStepJob.getSectionStepId(), beSectionStepJob.getSectionStepId(), 60 * 5);
                    if (!lock) {
                        //如果当前环节被锁，则继续处理下一环节
                        log.info("LOG[]AdvanceExecuteJobTask.execute{}", "环节id[" + beSectionStepJob.getSectionStepId() + "]正在执行中，本次不执行此环节");
                        continue;
                    }
                    long startTime = System.currentTimeMillis();
                    log.info("LOG[]AdvanceExecuteJobTask.execute{}", "环节id[" + beSectionStepJob.getSectionStepId() + "]开始提前执行任务");
                    BeSectionMethod beSectionMethod = beSectionMethodService.selectBySectionId(beSectionStepJob.getSectionId());
                    beSectionStepJobService.callSectionJob(beSectionStepJob.getSectionStepId(), beSectionMethod.getSubmitCode(), StepStage.BeforeFlow, null, null, "0", Constants.TWO);
                    log.info("LOG[]AdvanceExecuteJobTask.execute{}", "环节id[" + beSectionStepJob.getSectionStepId() + "]结束提前执行任务耗时：" + (System.currentTimeMillis() - startTime) / 1000 + "s");
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                    log.error("LOG[]AdvanceExecuteJobTask.execute{}", "环节id[" + beSectionStepJob.getSectionStepId() + "]提前执行环节任务异常");
                } finally {
                    //释放锁标识
                    RedisLockTool.releaseDistributedLock(RedisUtil.getJedis(), ADVANCE_EXECUTE_JOB_LOCK + beSectionStepJob.getSectionStepId(), beSectionStepJob.getSectionStepId());
                }
            }
        }
    }
}
